package com.didispace.hystrixCommand;

import com.didispace.web.User;
import com.netflix.hystrix.HystrixCommand;
import com.netflix.hystrix.HystrixCommandGroupKey;
import com.netflix.hystrix.HystrixCommandKey;
import com.netflix.hystrix.HystrixRequestCache;
import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategyDefault;
import org.springframework.web.client.RestTemplate;

// 第5章  服务容错保护： Spring Cloud Hystrix -- 使用详解 -- 请求缓存 -- 清理失效缓存功能
public class UserGetCommand extends HystrixCommand<User> {

    private static final HystrixCommandKey GETTER_KEY = HystrixCommandKey.Factory.asKey("CommandKey" );
    private RestTemplate restTemplate;
    private String name;
    private int age;

    public UserGetCommand(RestTemplate restTemplate, String name, int age) {
        super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey
                ("GetSetGet" ))
                .andCommandKey(GETTER_KEY));
        this.restTemplate = restTemplate;
        this.name = name;
        this.age = age;
    }

    @Override
    protected User run() {
        // return restTemplate.getForObject("http://localhost:8081/users/{1}", User.class, id); // 书上的运行不正确  p152
        //本地请求
        return restTemplate.getForEntity("http://localhost:8081/user2?name={1}&age={2}", User.class, name, age).getBody();
    }

    /**
     * 降级。Hystrix会在run()执行过程中出现错误、超时、线程池拒绝、断路器熔断等情况时， 执行getFallBack()方法内的逻辑
     */
    @Override
    protected User getFallback() {
        return new User("error", 0);
    }

    // 开启缓存
    @Override
    protected String getCacheKey() {
        // 根据name置入缓存
        return name;
    }

    // 清理缓存
    public static void flushCache(String name) {
        //刷新缓存，根据name进行清理  从默认的 Hystrix 并发策略中根据 GETTER—KEY 获取到该命令的请求缓存对象 HystrixRequestCache 的实例，
        // 然后再调用该请求缓存对象实例的 clear 方法，对 Key 为更新 User 的 id（此处为 name） 值的缓存内容进行清理。  p162
        HystrixRequestCache.getInstance(GETTER_KEY,
                HystrixConcurrencyStrategyDefault.getInstance()).clear(String.valueOf(name));
    }
}

